import redis
import json
import pickle
import logging
from typing import Any, Optional

class RedisClient:
    """
    Redis客户端封装类
    提供统一的Redis操作接口
    """

    def __init__(self, redis_config):
        """
        初始化Redis连接
        :param redis_config: Redis配置字典
        """
        self.redis_config = redis_config
        self.client = None
        self.connect()

    def connect(self):
        """
        建立Redis连接
        """
        try:
            self.client = redis.Redis(
                host=self.redis_config['host'],
                port=self.redis_config['port'],
                db=self.redis_config['db'],
                password=self.redis_config.get('password'),
                decode_responses=False  # 使用pickle序列化，不自动解码
            )
            # 测试连接
            self.client.ping()
            logging.info("Redis连接成功")
        except Exception as e:
            logging.error(f"Redis连接失败: {str(e)}")
            raise

    def set(self, key: str, value: Any, ex: Optional[int] = None):
        """
        设置键值对
        :param key: 键
        :param value: 值（任意Python对象）
        :param ex: 过期时间（秒）
        """
        try:
            serialized_value = pickle.dumps(value)
            self.client.set(key, serialized_value, ex=ex)
        except Exception as e:
            logging.error(f"Redis设置键值对失败: {str(e)}")
            raise

    def get(self, key: str) -> Any:
        """
        获取键对应的值
        :param key: 键
        :return: 值（任意Python对象）
        """
        try:
            serialized_value = self.client.get(key)
            if serialized_value is None:
                return None
            return pickle.loads(serialized_value)
        except Exception as e:
            logging.error(f"Redis获取键值对失败: {str(e)}")
            return None

    def delete(self, key: str) -> bool:
        """
        删除键
        :param key: 键
        :return: 是否删除成功
        """
        try:
            result = self.client.delete(key)
            return result > 0
        except Exception as e:
            logging.error(f"Redis删除键失败: {str(e)}")
            return False

    def exists(self, key: str) -> bool:
        """
        检查键是否存在
        :param key: 键
        :return: 是否存在
        """
        try:
            return self.client.exists(key) > 0
        except Exception as e:
            logging.error(f"Redis检查键是否存在失败: {str(e)}")
            return False

    def set_json(self, key: str, value: dict, ex: Optional[int] = None):
        """
        设置JSON格式的键值对
        :param key: 键
        :param value: 字典值
        :param ex: 过期时间（秒）
        """
        try:
            json_value = json.dumps(value)
            self.client.set(key, json_value, ex=ex)
        except Exception as e:
            logging.error(f"Redis设置JSON键值对失败: {str(e)}")
            raise

    def get_json(self, key: str) -> Optional[dict]:
        """
        获取JSON格式的值
        :param key: 键
        :return: 字典值
        """
        try:
            json_value = self.client.get(key)
            if json_value is None:
                return None
            return json.loads(json_value)
        except Exception as e:
            logging.error(f"Redis获取JSON键值对失败: {str(e)}")
            return None

    def clear_specific_cache(self, keys):
        """
        清除指定键的缓存
        :param keys: 要清除的键列表
        :return: 清除的键数量
        """
        try:
            if isinstance(keys, str):
                keys = [keys]
            if keys:
                deleted_count = self.redis_client.delete(*keys)
                return deleted_count
            return 0
        except Exception as e:
            print(f"清除指定Redis缓存失败: {e}")
            return 0

    def clear_cache(self, pattern="*"):
        """
        清除Redis缓存
        :param pattern: 匹配模式，默认为"*"清除所有缓存
        :return: 清除的键数量
        """
        try:
            # 获取所有匹配的键
            keys = self.client.keys(pattern)
            if keys:
                # 删除所有匹配的键
                deleted_count = self.client.delete(*keys)
                logging.info(f"成功清除 {deleted_count} 个键")
                return deleted_count
            logging.info("没有匹配的键需要清除")
            return 0
        except Exception as e:
            logging.error(f"清除Redis缓存失败: {e}")
            return 0
    def flush_all(self):
        """
        清空所有数据库中的所有键，等同于 redis-cli FLUSHALL
        :return: 布尔值表示操作是否成功
        """
        try:
            # 使用 flushall 命令清空所有数据库
            result = self.client.flushall()
            logging.info("成功执行 FLUSHALL，清空所有数据库")
            return result
        except Exception as e:
            logging.error(f"执行 FLUSHALL 失败: {e}")
            return False
    def flush_db(self):
        """
        清空当前数据库中的所有键，等同于 redis-cli FLUSHDB
        :return: 布尔值表示操作是否成功
        """
        try:
            # 使用 flushdb 命令清空当前数据库
            result = self.client.flushdb()
            logging.info("成功执行 FLUSHDB，清空当前数据库")
            return result
        except Exception as e:
            logging.error(f"执行 FLUSHDB 失败: {e}")
            return False

    def close(self):
        """
        关闭Redis连接
        """
        if self.client:
            self.client.close()

if __name__ == '__main__':
    redis_config = {
        'host': 'localhost',
        'port': 6379,
        'db': 0
    }
    redis_client = RedisClient(redis_config)
    redis_client.connect()
    # redis_client.set('key', 'value')
    # print(redis_client.get('key'))
    # redis_client.delete('key')
    redis_client.flush_db()
    redis_client.flush_all()